#!/usr/bin/env python
#Copyright (c) <2012> <Steven Sugg>
#
#Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

# First Release version uploaded to googlecode
# Version 0100r
# this script was created using concepts from several others in the public domain
# 1/17/2012 - This script is being used by geektool to:
#   1. Keep checking to make sure I have all of the available dilberts
#       to keep the library up to date (e.g. in case one was deleted by accident)
#   2. Get the latest Dilbert for display on my desktop

# import libraries
import sys, datetime, os, time
from datetime import timedelta
from time import strftime

######################################################
# globals globals globals globals globals globals
######################################################
# don't change these
dilbert_page_url_str = 'http://dilbert.com/fast/'
dilbert_strip_url_str = 'http://dilbert.com/'
todays_date = datetime.datetime.now().date()

# if your script is not executing properly, you can try increasing the delay
# experimentation has shown that 0.75 should work for most systems
# (your mileage may vary)
my_delay = 0.75

# change this to reflect your local file structure
my_dilbert_folder = '/users/steve/documents/dilberts/'

# the first dilbert strip was 4/17/1989
# set this to however far back you want to go
# as of 2/1/2012, this represents over 8,300 strips
start_date = datetime.date(1989, 4, 17)

# to debug, change one or both of these to True
debug = False
debug_detail = False

######################################################


# for backwards compatibility
if sys.version_info[0] > 2:
	import urllib.request as ul
else:
	import urllib as ul

# produces every legal date between start_date and end_date, inclusive
# - e.g. handles months with 30 or 31 days, leap years, etc.
def daterange(start_date, end_date):
    for n in range((end_date - start_date).days+1):
        yield start_date + timedelta(n)

# get one strip
def strip(date_str, save_as = ''):
# if no filename specified or if directory
	if save_as == '' or save_as[-1] == '\\' or save_as[-1] == '/':
		save_as += date_str + '.gif'
	
	if debug:
		print 'save_as: ' + save_as
	
	try:
		# str() is faster than decode() when converting from byte array to string
		myhtml = str(ul.urlopen(dilbert_page_url_str + date_str).read())
		# start search at 1000 since dyn is located around 1100-1400
		dyn_pos = myhtml.find('dyn', 1000)
		if dyn_pos != -1:
			mygif = myhtml[dyn_pos : myhtml.find('gif', dyn_pos)] + 'gif'
			
			if debug_detail:
				print 'mygif: ' + mygif
			
			# if it's an actual strip and not a placeholder: len('dyn/str_strip/default_th.gif') == 28
			if len(mygif) != 28:
				result = ul.urlretrieve(dilbert_strip_url_str + mygif, save_as)[0]

				if debug_detail:
					print 'result: ' + result

                # check to see if it is a new strip - name will correspond to today's date
                # if so, save another copy with the name LatestDilbert.gif, so geek tool can pick it up for display
				today_str = strftime("%Y%m%d", todays_date.timetuple())
				if result != None and today_str == date_str:
					ul.urlretrieve(dilbert_strip_url_str + mygif, my_dilbert_folder + 'LatestDilbert.gif')
				return result
	except:
		return None

# check all possible date combinations going back to the first dilbert
# if we dont' already have a strip with the correct name (based on date), then
#   try to get it. This is an elegant method using python's intrinsic range capabilites,
#	along with timedelta

def strips(begin = start_date, end = todays_date, save_loc = my_dilbert_folder, delay = my_delay):

	if debug:
		print 'GLOBALS'
		print '-------'
		print 'dilbert_page_url_str: ',
		print dilbert_page_url_str
		print 'dilbert_strip_url_str: ',
		print dilbert_strip_url_str
		print 'todays_date: ',
		print todays_date
		print 'my_delay: ',
		print my_delay
		print 'start_date: ',
		print start_date
		print 'my_dilbert_folder: ',
		print my_dilbert_folder
		print ''
		print 'begin: ',
		print begin
		print 'end: ',
		print end
		print 'save_loc: ' + save_loc
		start_time = datetime.datetime.now()
		print 'start_time: ',
		print start_time
	
	try:
		if save_loc != '' and not(os.path.isdir(save_loc)):
			os.makedirs(save_loc)
	except:
		save_loc = ''
	
	for my_date in daterange(begin, end):
		my_date_str = strftime("%Y%m%d", my_date.timetuple())
		
		if debug_detail:
			print 'checking date: ',
			print my_date_str
		
		if not os.path.exists(save_loc + my_date_str + '.gif'):
			if(strip(my_date_str, save_loc)) != None:
				time.sleep(delay)

	if debug:
		end_time = datetime.datetime.now()
		elapsed_time = end_time - start_time
		print 'end_time: ',
		print end_time
		print 'elapsed_time: ',
		print elapsed_time

#	built-in way to "kickstart" python scripts
if __name__ == '__main__':
	strips()
